package core.process.pack;

import core.utils.EPara;
import core.rb.PB;
import core.rb.r.Pol;
import gui.processor.Processor;
import gui.utils.ProgBar;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class IndelPack extends Thread{
    private Processor gp;
    protected PB pIn;
    protected IndelData pOut;
    protected final CountDownLatch stopLatch;
    public IndelPack(Processor gp, CountDownLatch stopLatch, PB packin){
        this.gp = gp;
        this.pIn = packin;
        this.stopLatch = stopLatch;
        this.start();
    }

    public void run(){
        pOut = getTIndelFreqs();
        stopLatch.countDown();
    }

    public IndelData getPOut(){return pOut;}

    private IndelData getTIndelFreqs() {
        int[][] dels = new int[EPara.MAXINDEL][pIn.getRef().getDNA().length()];
        int[][] ins = new int[EPara.MAXINDEL][pIn.getRef().getDNA().length()];
        ArrayList <Pol> pols; int c;
        if(gp!=null){
            gp.dPrg(ProgBar.START, pIn.getSize());
            for (int x = 0; x < pIn.getSize(); x++) {
                pols = pIn.getRead(x).getPols();
                for(int y = 0; y < pols.size(); y++){
                    c = 0;
                    if(pols.get(y).isIns()) {
                        do {c++;}while ((c + y) < pols.size() && pols.get(c + y).isIns() && pols.get(c + y).getTLoc() == pols.get(y).getTLoc());
                        if(c != 0 && c < EPara.MAXINDEL){ins[c][pols.get(y).getTLoc()]++;}
                        y += c - 1;
                    }else if (pols.get(y).getChar() == '-') {
                        do{c++;}while ((c + y) < pols.size() && pols.get(c + y).isDel() && pols.get(c + y).getTLoc() == (pols.get(y).getTLoc()+c));
                        if(c != 0 && c < EPara.MAXINDEL){dels[c][pols.get(y).getTLoc()]++;}
                        y += c - 1;
                    }
                }
                gp.dPrg(ProgBar.UPDATE, x);
            }
            gp.dPrg(ProgBar.END, 0);
        }
        else{
            for (int x = 0; x < pIn.getSize(); x++) {
                pols = pIn.getRead(x).getPols();
                for(int y = 0; y < pols.size(); y++){
                    c = 0;
                    if(pols.get(y).isIns()) {
                        do {c++;}while ((c + y) < pols.size() && pols.get(c + y).isIns() && pols.get(c + y).getTLoc() == pols.get(y).getTLoc());
                        if(c != 0 && c < EPara.MAXINDEL){ins[c][pols.get(y).getTLoc()]++;}
                        y += c - 1;
                    }else if (pols.get(y).getChar() == '-') {
                        do{c++;}while ((c + y) < pols.size() && pols.get(c + y).isDel() && pols.get(c + y).getTLoc() == (pols.get(y).getTLoc()+c));
                        if(c != 0 && c < EPara.MAXINDEL){dels[c][pols.get(y).getTLoc()]++;}
                        y += c - 1;
                    }
                }
            }
        }
        return new IndelData(ins, dels);
    }

}